import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

/**
 * Class describe studied words in DB
 * @author anton
 * @version 0.01
 */
public class EW_StudiedWords extends DataBaseAccess {
	
	/** Table name in DB */
	static public String TABLE_NAME = "StudiedWords";
	/** variable describe how many words should be selected from db */
	private int neededWordsCount = 0;
	/** variable describe how many good answers in one points */ 
	private int TENS_DEVISION = 10;
	
	/** id from table vocabulary describe counts of points for word */
	private int wordId;
	/** how many good answers is given*/
	private int tensCount;
	/** current points for word */
	private double points;
	/** for which profile is points count*/
	private String profile;
	/** current word*/
	private EW_Vocabulary curWord = null;
	/** remember how current record is get, from db or by created new */
	private boolean isNew = true;
	
	/**
	 * Constructor for class
	 * @param needWordsCount - how many words should class try to find in DB
	 * @param profileName - for which profile
	 */
	public EW_StudiedWords(int needWordsCount, String profileName) {
		super(TABLE_NAME);
		neededWordsCount = needWordsCount;
		profile = profileName; 
	}
	/**
	 * return word by given wordId
	 * @return EW_Vocabulary if word is not find yet it will try to find from db <br>
	 * else return from variable curWord
	 */
	public EW_Vocabulary getCurrentWord(){
		if (curWord == null) {
			curWord = new EW_Vocabulary(wordId);
		}
		return curWord;
	}
	
	/**
	 * set new count of needed words
	 * @param count - integer new count
	 */
	public void setNeedsCount(int count){
		neededWordsCount = count;
	}
	
	/**
	 * Set current word for studied words
	 * @param word - new EV_Vocabulary
	 */
	public void setCurrentWord(EW_Vocabulary word){
		if (word.getId() == 0){
			//TO DO сделать сообщение о том что так делать нельзя
		}
		else {
			curWord = word;
			wordId = word.getId();
		}
	}
	
	/**
	 * get good answer tens count
	 * @return - integer tens count
	 */
	public int getTensCount(){
		return tensCount;
	}
	/**
	 * set new value of points for current word 
	 * @param addedPoints - how many points need to by added for current points
	 */
	public void setPoints(double addedPoints){
		points += addedPoints;
		if (points < 0.00)
			points = 0;
		long round = Math.round(points);
		tensCount = (int) Math.floor(round/TENS_DEVISION);
	}
	
	@Override
	protected final ResultSet getListByDetail(HashMap<?, ?> keys) {
		String selectSQL = "SELECT sw.* FROM StudiedWords sw ";
		if (keys.get("topicName") != null){
			selectSQL += "JOIN WordInTopic wit on sw.wordId = wit.wordId ";
		}
		selectSQL += "WHERE ";
		int keysCount = keys.size();
		if (keysCount == 0)	{
			selectSQL += " 1 = 1";
		}
		else {
			if (keys.get("tensCount") != null){
				selectSQL += " sw.tensCount " +	keys.get("tensCount");
				if (keysCount > 1){
					selectSQL += " and ";
					keysCount--;
				}
			};
			if (keys.get("lastAsk") != null){
				selectSQL += " sw.lastAsk <= '" +	keys.get("lastAsk") + "'";
				if (keysCount > 1){
					selectSQL += " and ";
					keysCount--;
				}
			};
			if (keys.get("name") != null){
				selectSQL += " sw.profile = '" +	keys.get("name") + "'";
				if (keysCount > 1){
					selectSQL += " and ";
					keysCount--;
				}
			};
			
			if (keys.get("topicName") != null){
				selectSQL += " wit.topicName = '" + keys.get("topicName") + "'";
			}
		};
		
		selectSQL += " ORDER BY lastAsk";
		
		try {
			EWDataBase db = EWDataBase.getInstance();
			return db.conn.prepareStatement(selectSQL).executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * looking for records in db by required parameters
	 * @param keys array of request parameters key can be:
	 * 	1 - tensCount, required sign and value such as: </br>
	 *			* < 10 </br>
	 * 			* > 10 </br>
	 * 			* = 10 </br>
	 * 			* BETWEEN 10 AND 20 </br>
	 * 			* IN (10, 20)</br>
	 *  2 - lastAsk, should be time stamp data looking for records less then lastAsk </br>
	 *  3 - name, name of current profile
	 * @return list of EW_StudiedWords from table StudiedWords
	 */
	public ArrayList<EW_StudiedWords> getList(HashMap<String, String> keys){
		ArrayList<EW_StudiedWords> list = new ArrayList<EW_StudiedWords>();
		try {
			ResultSet rs = getListByDetail(keys);
			while (rs.next()) {
				EW_StudiedWords item = new EW_StudiedWords(1, rs.getString("profile"));
				item.wordId = rs.getInt("wordID");
				item.points = rs.getFloat("points");
				item.isNew = false;
				list.add(item);
				
				if (list.size() == this.neededWordsCount){
					rs.close();
					return list;
				}
			}
			rs.close();
			return list;
		} 
		catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * insert current studied word in DB
	 * @return - integer result of insert
	 */
	public int insertCurrentRecord(){
		if (!isNew) { 
			return updateCurrentRecord();
		} 
		else {
			HashMap<String, String> insertValues = new HashMap<String, String>();
			insertValues.put("lastAsk".toUpperCase(), new Timestamp(new Date().getTime()).toString());
			insertValues.put("tensCount".toUpperCase(), ((Integer)tensCount).toString());
			insertValues.put("points".toUpperCase(), ((Double)points).toString()); 
			insertValues.put("profile".toUpperCase(), profile);
			insertValues.put("wordID".toUpperCase(), ((Integer)wordId).toString());
			return super.insertOneRecord(insertValues);
		}
	}
	
	/**
	 * update current studied word in db
	 * @return - integer result of update
	 */
	public int updateCurrentRecord(){
		ArrayList<String> where = new ArrayList<String>();
		where.add("wordID = " + ((Integer)wordId).toString());
		where.add("profile = '" + profile + "'");
		
		ArrayList<String> sets = new ArrayList<String>();
		sets.add("lastAsk = '" + new Timestamp(new Date().getTime()).toString() + "'");
		sets.add("tensCount = " + ((Integer)tensCount).toString());
		sets.add("points = " + ((Double)points).toString()); 
		
		return super.updateOneRecord(where, sets);
	}
}
